import("stdfaust.lib");
sp = library("spats.lib");
ba = library("basics.lib");
// lmms的调制链 osc3->osc2->osc1;
/*
那么实际计算顺序是：

先计算 OSC3（最底层）
用 OSC3 的输出去调制 OSC2
即：OSC2 = modulate(OSC2_base, OSC3)
再用 OSC2 的输出去调制 OSC1
即：OSC1 = modulate(OSC1_base, OSC2)
*/
// 振荡器参数控件
osc1_volume = hslider("OSC1 VOL[style:knob]",1,0,1,0.1);
osc2_volume = hslider("OSC2 VOL[style:knob]",1,0,1,0.1);
osc3_volume = hslider("OSC3 VOL[style:knob]",1,0,1,0.1);

osc1_pan = hslider("OSC1 PAN[style:knob]",0.5,0,1,0.1);
osc2_pan = hslider("OSC2 PAN[style:knob]",0.5,0,1,0.1);
osc3_pan = hslider("OSC3 PAN[style:knob]",0.5,0,1,0.1);

osc1_coarse = hslider("OSC1 CRS[style:knob][unit:半音]",0,-24,24,1);
osc1_fine = hslider("OSC1 FINE[style:knob][unit:音分]",0,-100,100,1);
osc1_phase = hslider("OSC1 PHASE[style:knob][unit:°]", 0, 0, 1, 0.01);

osc2_coarse = hslider("OSC2 CRS[style:knob][unit:半音]",0,-24,24,1);
osc2_fine = hslider("OSC2 FINE[style:knob][unit:音分]",0,-100,100,1);
osc2_phase = hslider("OSC2 PHASE[style:knob][unit:°]",0,0,1,0.01);

osc3_coarse = hslider("OSC3 CRS[style:knob][unit:半音]",0,-24,24,1);
osc3_fine = hslider("OSC3 FINE[style:knob][unit:音分]",0,-24,24,1);
osc3_phase = hslider("OSC3 PHASE[style:knob][unit:°]",0,0,1,0.01);

// 波形选择器
osc1_wave_selector = vslider("OSC1 WAVE[style:knob{'sin':0,'tri':1,'saw':2,'square':3}]",0,0,3,1);
osc2_wave_selector = vslider("OSC2 WAVE[style:knob{'sin':0,'tri':1,'saw':2,'square':3}]",0,0,3,1);
osc3_wave_selector = vslider("OSC3 WAVE[style:knob{'sin':0,'tri':1,'saw':2,'square':3}]",0,0,3,1);

// 调制模式选择器 - 分开显示
osc1_osc2_modulate_selector = vslider("OSC1+OSC2[style:knob{'AM':0,'MIX':1,'FM':2}]",0,0,2,1);
osc2_osc3_modulate_selector = vslider("OSC2+OSC3[style:knob{'AM':0,'MIX':1,'FM':2}]",0,0,2,1);

// 频率计算
osc1_freq = 440 * detuneRatio(osc1_coarse,osc1_fine);
osc2_freq = 440 * detuneRatio(osc2_coarse,osc2_fine);
osc3_freq = 440 * detuneRatio(osc3_coarse,osc3_fine);

// 左右声道相位偏移计算
phase1_left = phase1_offset + stereo_phase1;
phase1_right = phase1_offset;

phase2_left = phase2_offset + stereo_phase2;
phase2_right = phase2_offset;

phase3_left = phase3_offset + stereo_phase3;
phase3_right = phase3_offset;

// 立体声相位差参数
stereo_phase1 = hslider("Osc1/Stereo Phase Diff[0-1]", 0, 0, 1, 0.01);
stereo_phase2 = hslider("Osc2/Stereo Phase Diff[0-1]", 0, 0, 1, 0.01);
stereo_phase3 = hslider("Osc3/Stereo Phase Diff[0-1]", 0, 0, 1, 0.01);
// 波形生成函数
wave(freq,selector) =
  (os.osc(freq),os.triangle(freq),os.sawtooth(freq),os.square(freq)):ba.selectn(4,selector);

// 生成单声道振荡器信号
osc1_signal = wave(osc1_freq,osc1_wave_selector) * osc1_volume;
osc2_signal = wave(osc2_freq,osc2_wave_selector) * osc2_volume;
osc3_signal = wave(osc3_freq,osc3_wave_selector) * osc3_volume;

// 调制函数
am(osc1,osc2) = osc1 * (1+osc2);
mix(osc1,osc2) = (osc1 + osc2)/2;
fm(osc1,osc2) = osc1 * (1+osc2/2);

// 调制类型选择函数
changeModulateType(selector, osc1, osc2) = 
  am(osc1,osc2), mix(osc1,osc2), fm(osc1,osc2) : ba.selectn(3,selector);

modulated_osc2 = changeModulateType(osc2_osc3_modulate_selector,osc2_signal,osc3_signal);
modulated_final = changeModulateType(osc1_osc2_modulate_selector, osc1_signal, modulated_osc2);
// 应用立体声定位
osc1_stereo = hgroup("OSC1", osc1_signal : sp.panner(osc1_pan));
osc2_stereo = hgroup("OSC2", osc2_signal : sp.panner(osc2_pan));
osc3_stereo = hgroup("OSC3", osc3_sginal : sp.panner(osc3_pan));

// 混合所有信号到立体声输出
left_channel = 
    hgroup("final",modulated_final);

right_channel = 
    hgroup("final",modulated_final);

process = hgroup("final",modulated_final);

// 辅助函数
detuneRatio(coarse, fine) = 2^(coarse/12 + fine/1200);